/**
 * Copyright 2011 Joe Choi, All rights reserved.
 */
package tao.calendar.gregorian;

import java.util.Calendar;

import tao.time.Time;

/**
 * The ConcreteOperatableDate class is concrete implementation of OperatableDate interface
 * 
 * @author Joe Choi
 * @version 1.0.0
 */
class ConcreteOperatableDate extends ConcreteGregorianDate implements OperatableDate {
	public ConcreteOperatableDate(GregorianDate date) {
		super(date);
	}

	@Override
	public Operatable roll(GregorianUnitAmount amount) {
		int year = getYear();
		int month = getMonth();
		int day = getDay();
		
		switch(amount.getUnit()) {
			case Year : year += amount.getValue(); 
						break; 
			case Month : month += amount.getValue(); 
						break; 
			case Day : day += amount.getValue(); break;
		}
		
		normalizeWithoutEra(year, month, day);
		return(this);
	}
	
	@Override
	public Operatable add(GregorianUnitAmount amount) {
		Calendar c = getCalendar();
		c.setTimeInMillis(scalar());
		
		switch(amount.getUnit()) {
			case Year : c.add(Calendar.YEAR, (int) amount.getValue()); break; 
			case Month : c.add(Calendar.MONTH, (int) amount.getValue()); break; 
			case Day : c.add(Calendar.DAY_OF_MONTH, (int) amount.getValue()); break;
		}
		construct(c.getTimeInMillis());
		return(this);
	}
	
	@Override
	public GregorianAmount diff(Time otherTime) {
		long otherScalar = truncateDayTime(otherTime.scalar());
		return(constructAmount(Math.abs(scalar() - otherScalar)));
	}
	
	private GregorianAmount constructAmount(long scalar) {
		long days = scalar / GregorianTime.DAY_MILLIS;
		return(Gregorian.dateAmount(0, 0, (int) days));
	}	
}
